Avastage võimas failisüsteemi juurdepääsu API, mis võimaldab veebirakendustel turvaliselt lugeda, kirjutada ja hallata kohalikke faile. Põhjalik juhend arendajatele.
Kohaliku failisüsteemi avamine: sügav sissevaade esiotsa failisüsteemi juurdepääsu API-sse
Aastakümneid on brauser olnud liivakasti keskkond – turvaline, kuid põhimõtteliselt piiratud ruum. Üks selle kõige jäigemaid piire on olnud kohalik failisüsteem. Veebirakendused võisid paluda teil faili üles laadida või alla laadida, kuid idee veebipõhisest tekstiredaktorist, mis avab faili, laseb teil seda redigeerida ja salvestab selle täpselt samasse kohta tagasi, oli puhas ulme. See piirang on olnud peamine põhjus, miks töölauarakendused on säilitanud oma eelise ülesannete puhul, mis nõuavad intensiivset failimanipulatsiooni, nagu videotöötlus, tarkvaraarendus ja graafiline disain.
See paradigma on nüüd muutumas. Failisüsteemi juurdepääsu API (File System Access API), varem tuntud kui Native File System API, purustab selle pikaaegse tõkke. See pakub veebiarendajatele standardiseeritud, turvalise ja võimsa mehhanismi failide ja kataloogide lugemiseks, kirjutamiseks ja haldamiseks kasutaja kohalikus masinas. See ei ole turvanõrkus; see on hoolikalt väljatöötatud areng, mis annab kasutajale täieliku kontrolli selgesõnaliste lubade kaudu.
See API on järgmise põlvkonna progressiivsete veebirakenduste (PWA) nurgakivi, andes neile võimalused, mis olid kunagi ainuomased natiivsele tarkvarale. Kujutage ette veebipõhist IDE-d, mis suudab hallata kohalikku projektikausta, fototöötlusprogrammi, mis töötab otse teie kõrge eraldusvõimega piltidega ilma üleslaadimiseta, või märkmete tegemise rakendust, mis salvestab markdown-faile otse teie dokumentide kausta. See on tulevik, mille failisüsteemi juurdepääsu API võimalikuks teeb.
Selles põhjalikus juhendis uurime selle murrangulise API kõiki tahke. Süveneme selle ajalukku, mõistame selle põhilisi turvaprintsiipe, käime läbi praktilisi koodinäiteid lugemise, kirjutamise ja kataloogihalduse kohta ning arutame täiustatud tehnikaid ja reaalseid kasutusjuhtumeid, mis inspireerivad teie järgmist projekti.
Failikäsitluse areng veebis
Et tõeliselt hinnata failisüsteemi juurdepääsu API olulisust, on kasulik vaadata tagasi sellele, kuidas brauserid on kohalikke faile käsitlenud. Teekond on olnud järkjärguline ja turvalisusele keskendunud iteratsioon.
Klassikaline lähenemine: sisendid ja ankrud
Algupärased meetodid failidega suhtlemiseks olid lihtsad ja rangelt kontrollitud:
- Failide lugemine: Element
<input type="file">on olnud aastaid failide üleslaadimise tööloom. Kui kasutaja valib faili (või mitu faili atribuudigamultiple), saab rakendusFileListobjekti. Arendajad saavad seejärel kasutadaFileReaderAPI-d, et lugeda nende failide sisu mällu stringina, ArrayBufferina või andme-URL-ina. Rakendus ei saa aga kunagi teada faili algset asukohta ja tal pole võimalust sinna tagasi kirjutada. Iga 'salvestamise' toiming on tegelikult 'allalaadimine'. - Failide salvestamine: Salvestamine oli veelgi kaudsem. Levinud tehnika hõlmab
<a>(ankur) sildi loomist, sellehrefatribuudi seadmist andme-URI-le või Blob URL-ile,downloadatribuudi lisamist koos soovitatud failinimega ja selle programmilist klõpsamist. See toiming avab kasutajale 'Salvesta nimega...' dialoogi, mis vaikimisi avaneb tavaliselt tema 'Allalaadimiste' kaustas. Kasutaja peab käsitsi navigeerima õigesse asukohta, kui ta soovib olemasolevat faili üle kirjutada.
Vanade meetodite piirangud
Kuigi funktsionaalne, seadis see klassikaline mudel keerukate rakenduste loomisele olulisi piiranguid:
- Olekuta interaktsioon: Ühendus failiga kaob kohe pärast selle lugemist. Kui kasutaja redigeerib dokumenti ja soovib selle salvestada, ei saa rakendus lihtsalt originaali üle kirjutada. Ta peab alla laadima uue koopia, sageli muudetud nimega (nt 'dokument(1).txt'), mis viib failide kuhjumiseni ja segase kasutajakogemuseni.
- Kataloogidele juurdepääsu puudumine: Puudus kausta mõiste. Rakendus ei saanud paluda kasutajal avada tervet projektikataloogi, et selle sisuga töötada, mis on iga veebipõhise IDE või koodiredaktori põhiline nõue.
- Kasutaja hõõrdumine: Pidev tsükkel 'Ava...' -> 'Redigeeri' -> 'Salvesta nimega...' -> 'Navigeeri...' -> 'Kirjuta üle?' on kohmakas ja ebaefektiivne võrreldes lihtsa 'Ctrl + S' või 'Cmd + S' kogemusega natiivsetes rakendustes.
Need piirangud taandasid veebirakendused ajutiste failide tarbijateks ja loojateks, mitte kasutaja kohalike andmete püsivateks redaktoriteks. Failisüsteemi juurdepääsu API loodi nende puuduste otseseks lahendamiseks.
Sissejuhatus failisüsteemi juurdepääsu API-sse
Failisüsteemi juurdepääsu API on kaasaegne veebistandard, mis pakub otseühendust, ehkki lubadepõhist, kasutaja kohaliku failisüsteemiga. See võimaldab arendajatel luua rikkalikke, töölauaklassi kogemusi, kus faile ja katalooge käsitletakse esmaklassiliste kodanikena.
Põhimõisted ja terminoloogia
API mõistmine algab selle võtmeobjektidest, mis toimivad failisüsteemi elementide käepidemete või viidetena.
FileSystemHandle: See on nii failide kui ka kataloogide baasliides. See esindab ühte kirjet failisüsteemis ja sellel on omadused nagunamejakind('file' või 'directory').FileSystemFileHandle: See liides esindab faili. See päribFileSystemHandle'ist ja pakub meetodeid faili sisuga suhtlemiseks, näiteksgetFile()standardseFileobjekti saamiseks (metaandmete või sisu lugemiseks) jacreateWritable()andmete kirjutamiseks voo saamiseks.FileSystemDirectoryHandle: See esindab kataloogi. See võimaldab teil loetleda kataloogi sisu või saada käepidemeid konkreetsetele failidele või alamkataloogidele, kasutades meetodeid nagugetFileHandle()jagetDirectoryHandle(). Samuti pakub see asünkroonseid iteraatoreid oma kirjete läbimiseks.FileSystemWritableFileStream: See on võimas voopõhine liides andmete faili kirjutamiseks. See võimaldab teil tõhusalt kirjutada stringe, Blobe või puhvreid ning pakub meetodeid konkreetsele positsioonile liikumiseks või faili kärpimiseks. Muudatuste kettale kirjutamise tagamiseks peate kutsuma selleclose()meetodi.
Turvamudel: kasutajakeskne ja turvaline
Veebisaidile otsejuurdepääsu andmine oma failisüsteemile on oluline turvakaalutlus. Selle API loojad on ehitanud robustse, lubadepõhise turvamudeli, mis seab esikohale kasutaja nõusoleku ja kontrolli.
- Kasutaja algatatud toimingud: Rakendus ei saa spontaanselt käivitada failivalijat. Juurdepääs peab olema algatatud otsese kasutaja tegevusega, näiteks nupuvajutusega. See takistab pahatahtlikel skriptidel teie failisüsteemi vaikselt skannimast.
- Valija on värav: API sisenemispunktid on valija meetodid:
window.showOpenFilePicker(),window.showSaveFilePicker()jawindow.showDirectoryPicker(). Need meetodid kuvavad brauseri natiivse faili/kataloogi valimise kasutajaliidese. Kasutaja valik on selgesõnaline loa andmine selle konkreetse elemendi jaoks. - Lubade küsimised: Pärast käepideme saamist võib brauser küsida kasutajalt 'lugemise' või 'lugemise-kirjutamise' lube selle käepideme jaoks. Kasutaja peab selle küsimuse heaks kiitma, enne kui rakendus saab jätkata.
- Lubade püsivus: Parema kasutajakogemuse tagamiseks võivad brauserid neid lube antud päritolu (veebisaidi) jaoks säilitada. See tähendab, et pärast seda, kui kasutaja on failile korra juurdepääsu andnud, ei küsita temalt seda uuesti sama seansi ajal ega isegi järgmistel külastustel. Loa olekut saab kontrollida meetodiga
handle.queryPermission()ja uuesti taotleda meetodigahandle.requestPermission(). Kasutajad saavad need load igal ajal oma brauseri seadete kaudu tühistada. - Ainult turvalised kontekstid: Nagu paljud kaasaegsed veebi API-d, on ka failisüsteemi juurdepääsu API saadaval ainult turvalistes kontekstides, mis tähendab, et teie veebisaiti tuleb serveerida HTTPS-i kaudu või localhostist.
See mitmekihiline lähenemine tagab, et kasutaja on alati teadlik ja kontrolli all, leides tasakaalu võimsate uute võimaluste ja vankumatu turvalisuse vahel.
Praktiline rakendamine: samm-sammuline juhend
Liigume teooriast praktikasse. Siin on, kuidas saate hakata kasutama failisüsteemi juurdepääsu API-d oma veebirakendustes. Kõik API meetodid on asünkroonsed ja tagastavad Promise'e, seega kasutame puhtama koodi jaoks kaasaegset async/await süntaksit.
Brauseri toe kontrollimine
Enne API kasutamist peate kontrollima, kas kasutaja brauser seda toetab. Piisab lihtsast funktsiooni tuvastamise kontrollist.
if ('showOpenFilePicker' in window) {
console.log('Suurepärane! Failisüsteemi juurdepääsu API on toetatud.');
} else {
console.log('Vabandust, see brauser ei toeta API-d.');
// Paku varuvariant <input type="file"> abil
}
Faili lugemine
Kohaliku faili lugemine on tavaline alguspunkt. Protsess hõlmab failivalija näitamist, faili käepideme saamist ja seejärel selle sisu lugemist.
const openFileButton = document.getElementById('open-file-btn');
openFileButton.addEventListener('click', async () => {
try {
// Meetod showOpenFilePicker() tagastab käepidemete massiivi,
// kuid selles näites huvitab meid ainult esimene.
const [fileHandle] = await window.showOpenFilePicker();
// Saa käepidemest File objekt.
const file = await fileHandle.getFile();
// Loe faili sisu tekstina.
const content = await file.text();
// Kasuta sisu (nt kuva see textarea's).
document.getElementById('editor').value = content;
} catch (err) {
// Käsitle vigu, näiteks kui kasutaja tühistab valija.
console.error('Viga faili avamisel:', err);
}
});
Selles näites tagastab window.showOpenFilePicker() promise'i, mis laheneb FileSystemFileHandle objektide massiiviga. Me destruktrueerime esimese elemendi oma fileHandle muutujasse. Sealt edasi annab fileHandle.getFile() standardse File objekti, millel on tuttavad meetodid nagu .text(), .arrayBuffer() ja .stream().
Faili kirjutamine
Kirjutamine on koht, kus API tõeliselt särab, kuna see võimaldab sujuvalt nii uute failide salvestamist kui ka olemasolevate ülekirjutamist.
Muudatuste salvestamine olemasolevasse faili
Laiendame meie eelmist näidet. Peame salvestama fileHandle'i, et saaksime seda hiljem muudatuste salvestamiseks kasutada.
let currentFileHandle;
// ... 'openFileButton' kliki kuulaja sees ...
// Pärast käepideme saamist showOpenFilePicker'ist:
currentFileHandle = fileHandle;
// --- NĂĽĂĽd seadistame salvestamisnupu ---
const saveFileButton = document.getElementById('save-file-btn');
saveFileButton.addEventListener('click', async () => {
if (!currentFileHandle) {
alert('Palun avage esmalt fail!');
return;
}
try {
// Loo kirjutamiseks FileSystemWritableFileStream.
const writable = await currentFileHandle.createWritable();
// Saa sisu meie redaktorist.
const content = document.getElementById('editor').value;
// Kirjuta sisu voogu.
await writable.write(content);
// Sulge fail ja kirjuta sisu kettale.
// See on ĂĽlioluline samm!
await writable.close();
alert('Fail on edukalt salvestatud!');
} catch (err) {
console.error('Viga faili salvestamisel:', err);
}
});
Võtmeetapid on createWritable(), mis valmistab faili kirjutamiseks ette, write(), mis saadab andmed, ja kriitiline close(), mis viimistleb toimingu ja salvestab muudatused kettale.
Uue faili salvestamine ('Salvesta nimega')
Uue faili salvestamiseks kasutate window.showSaveFilePicker(). See esitab 'Salvesta nimega' dialoogi ja tagastab uue FileSystemFileHandle valitud asukoha jaoks.
const saveAsButton = document.getElementById('save-as-btn');
saveAsButton.addEventListener('click', async () => {
try {
const newFileHandle = await window.showSaveFilePicker({
suggestedName: 'nimetu.txt',
types: [{
description: 'Tekstifailid',
accept: {
'text/plain': ['.txt'],
},
}],
});
// Nüüd, kui meil on käepide, saame kasutada sama kirjutamisloogikat nagu varem.
const writable = await newFileHandle.createWritable();
const content = document.getElementById('editor').value;
await writable.write(content);
await writable.close();
// Valikuliselt uuendame oma praeguse käepideme sellele uuele failile.
currentFileHandle = newFileHandle;
alert('Fail salvestati uude asukohta!');
} catch (err) {
console.error('Viga uue faili salvestamisel:', err);
}
});
Töötamine kataloogidega
Võimalus töötada tervete kataloogidega avab võimsaid kasutusjuhtumeid nagu veebipõhised IDE-d.
Esmalt laseme kasutajal valida kataloogi:
const openDirButton = document.getElementById('open-dir-btn');
openDirButton.addEventListener('click', async () => {
try {
const dirHandle = await window.showDirectoryPicker();
// Nüüd saame töödelda kataloogi sisu.
await processDirectory(dirHandle);
} catch (err) {
console.error('Viga kataloogi avamisel:', err);
}
});
Kui teil on FileSystemDirectoryHandle, saate selle sisu läbi itereerida, kasutades asünkroonset for...of tsüklit. Järgnev funktsioon loetleb rekursiivselt kõik failid ja alamkataloogid.
async function processDirectory(dirHandle) {
const fileListElement = document.getElementById('file-list');
fileListElement.innerHTML = ''; // TĂĽhjenda eelnev nimekiri
for await (const entry of dirHandle.values()) {
const listItem = document.createElement('li');
// Omadus 'kind' on kas 'file' või 'directory'
listItem.textContent = `[${entry.kind}] ${entry.name}`;
fileListElement.appendChild(listItem);
if (entry.kind === 'directory') {
// See näitab, et lihtne rekursiivne kutse on võimalik,
// kuigi täielik kasutajaliides käsitleks pesastamist teisiti.
console.log(`Leitud alamkataloog: ${entry.name}`);
}
}
}
Uute failide ja kataloogide loomine
Saate ka programmiliselt luua uusi faile ja alamkatalooge kataloogis, millele teil on juurdepääs. Selleks tuleb edastada valik { create: true } meetoditele getFileHandle() või getDirectoryHandle().
async function createNewFile(dirHandle, fileName) {
try {
// Saa käepide uuele failile, luues selle, kui seda ei eksisteeri.
const newFileHandle = await dirHandle.getFileHandle(fileName, { create: true });
console.log(`Loodud või saadud käepide failile: ${newFileHandle.name}`);
// Nüüd saate sellesse käepidemesse kirjutada.
} catch (err) {
console.error('Viga faili loomisel:', err);
}
}
async function createNewFolder(dirHandle, folderName) {
try {
// Saa käepide uuele kataloogile, luues selle, kui seda ei eksisteeri.
const newDirHandle = await dirHandle.getDirectoryHandle(folderName, { create: true });
console.log(`Loodud või saadud käepide kataloogile: ${newDirHandle.name}`);
} catch (err) {
console.error('Viga kataloogi loomisel:', err);
}
}
Täpsemad kontseptsioonid ja kasutusjuhud
Kui olete põhitõed selgeks saanud, saate uurida täpsemaid funktsioone, et luua tõeliselt sujuvaid kasutajakogemusi.
PĂĽsivus IndexedDB abil
Suur väljakutse on see, et FileSystemHandle objekte ei säilitata, kui kasutaja lehte värskendab. Selle lahendamiseks saate salvestada käepidemed IndexedDB-sse, brauseri kliendipoolsesse andmebaasi. See võimaldab teie rakendusel meeles pidada, milliste failide ja kaustadega kasutaja seansside vahel töötas.
Käepideme salvestamine on sama lihtne kui selle panemine IndexedDB objektihoidlasse. Selle kättesaamine on sama lihtne. Kuid load ei salvestata koos käepidemega. Kui teie rakendus uuesti laadib ja hangib käepideme IndexedDB-st, peate esmalt kontrollima, kas teil on endiselt luba, ja vajadusel seda uuesti taotlema.
// Funktsioon salvestatud käepideme hankimiseks
async function getHandleFromDB(key) {
// (Kood IndexedDB avamiseks ja käepideme saamiseks)
const handle = await getFromDB(key);
if (!handle) return null;
// Kontrolli, kas meil on endiselt luba.
if (await handle.queryPermission({ mode: 'readwrite' }) === 'granted') {
return handle; // Luba on juba antud.
}
// Kui ei, peame luba uuesti kĂĽsima.
if (await handle.requestPermission({ mode: 'readwrite' }) === 'granted') {
return handle; // Kasutaja andis loa.
}
// Luba keelati.
return null;
}
See muster võimaldab teil luua funktsiooni 'Hiljutised failid' või 'Ava hiljutine projekt', mis tundub täpselt nagu natiivne rakendus.
Lohistamise (Drag and Drop) integratsioon
API integreerub kaunilt natiivse lohistamise API-ga. Kasutajad saavad lohistada faile või kaustu oma töölaualt ja kukutada need teie veebirakendusse, et anda juurdepääs. See saavutatakse meetodi DataTransferItem.getAsFileSystemHandle() kaudu.
const dropZone = document.getElementById('drop-zone');
dropZone.addEventListener('dragover', (event) => {
event.preventDefault(); // Vajalik kukutamise lubamiseks
});
dropZone.addEventListener('drop', async (event) => {
event.preventDefault();
for (const item of event.dataTransfer.items) {
if (item.kind === 'file') {
const handle = await item.getAsFileSystemHandle();
if (handle.kind === 'directory') {
console.log(`Kataloog kukutatud: ${handle.name}`);
// Töötle kataloogi käepidet
} else {
console.log(`Fail kukutatud: ${handle.name}`);
// Töötle faili käepidet
}
}
}
});
Reaalse maailma rakendused
Selle API võimaldatud võimalused on laialdased ja suunatud globaalsele loojate ja professionaalide publikule:
- Veebipõhised IDE-d ja koodiredaktorid: Tööriistad nagu VS Code for the Web (vscode.dev) saavad nüüd avada kohaliku projektikausta, võimaldades arendajatel redigeerida, luua ja hallata kogu oma koodibaasi otse brauseris.
- Loomingulised tööriistad: Pildi-, video- ja heliredaktorid saavad laadida suuri meediafaile otse kasutaja kõvakettalt, teha keerukaid muudatusi ja salvestada tulemuse ilma aeglase üles- ja allalaadimisprotsessita serverist.
- Tootlikkus ja andmeanalüüs: Ärikasutaja saaks avada suure CSV- või JSON-faili veebipõhises andmete visualiseerimise tööriistas, analüüsida andmeid ja salvestada aruandeid, ilma et andmed kunagi tema masinast lahkuksid, mis on suurepärane privaatsuse ja jõudluse seisukohast.
- Mängimine: Veebipõhised mängud võiksid lubada kasutajatel hallata salvestatud mänge või installida modifikatsioone, andes juurdepääsu konkreetsele mängukaustale.
Kaalutlused ja parimad praktikad
Suure võimuga kaasneb suur vastutus. Siin on mõned peamised kaalutlused arendajatele, kes seda API-d kasutavad.
Keskendu kasutajakogemusele (UX)
- Selgus on võtmetähtsusega: Seo API-kutsed alati selgete, otseste kasutajatoimingutega, nagu nupud sildiga 'Ava fail' või 'Salvesta muudatused'. Ära kunagi üllata kasutajat failivalijaga.
- Anna tagasisidet: Kasuta kasutajaliidese elemente, et teavitada kasutajat toimingute olekust (nt 'Salvestan...', 'Fail on edukalt salvestatud', 'Luba keelatud').
- Sujuvad varuvariandid: Kuna API ei ole veel universaalselt toetatud, paku alati varumehhanismi, kasutades vanemates brauserites traditsioonilisi
<input type="file">ja ankru allalaadimismeetodeid.
Jõudlus
API on loodud jõudluse tagamiseks. Kaotades vajaduse serveri üles- ja allalaadimiste järele, võivad rakendused muutuda oluliselt kiiremaks, eriti suurte failidega tegelemisel. Kuna kõik toimingud on asünkroonsed, ei blokeeri need brauseri peamist lõime, hoides teie kasutajaliidese reageerimisvõimelisena.
Piirangud ja brauseri ĂĽhilduvus
Suurim kaalutlus on brauseri tugi. 2023. aasta lõpu seisuga on API täielikult toetatud Chromiumil põhinevates brauserites nagu Google Chrome, Microsoft Edge ja Opera. Tugi Firefoxis on arendamisel lipu taga ja Safari ei ole veel rakendamisega seotud. Globaalse publiku jaoks tähendab see, et te ei saa loota sellele API-le kui *ainsale* viisile failide käsitlemiseks. Kontrollige alati usaldusväärset allikat nagu CanIUse.com uusima ühilduvusteabe saamiseks.
Kokkuvõte: uus ajastu veebirakendustele
Failisüsteemi juurdepääsu API kujutab endast monumentaalset hüpet edasi veebiplatvormi jaoks. See tegeleb otse ühe kõige olulisema funktsionaalse lüngaga veebi- ja natiivsete rakenduste vahel, andes arendajatele võimaluse luua uut klassi võimsaid, tõhusaid ja kasutajasõbralikke tööriistu, mis töötavad täielikult brauseris.
Pakkudes turvalist, kasutaja kontrollitud silda kohaliku failisüsteemiga, parandab see rakenduste võimalusi, suurendab jõudlust, vähendades sõltuvust serveritest, ja sujuvdab töövooge kasutajatele üle kogu maailma. Kuigi peame olema teadlikud brauseri ühilduvusest ja rakendama sujuvaid varuvariante, on tee edasi selge. Veeb areneb sisu tarbimise platvormist küpseks loomisplatvormiks. Soovitame teil uurida failisüsteemi juurdepääsu API-d, katsetada selle võimalusi ja alustada juba täna järgmise põlvkonna veebirakenduste ehitamist.